const WebSocket = require('ws');
const express = require('express');
const path = require('path');
const os = require('os');

// 获取本机IP地址
function getLocalIP() {
    const interfaces = os.networkInterfaces();
    for (const name of Object.keys(interfaces)) {
        for (const iface of interfaces[name]) {
            // 跳过非IPv4和内部地址
            if (iface.family === 'IPv4' && !iface.internal) {
                return iface.address;
            }
        }
    }
    return '127.0.0.1';
}

// 创建express应用
const app = express();
const PORT = 3000;
const localIP = getLocalIP();

// 设置静态文件服务
app.use(express.static(path.join(__dirname, '../client')));

// 创建HTTP服务器
const server = app.listen(PORT, '0.0.0.0', () => {
    console.log(`P2P节点运行在 http://${localIP}:${PORT}`);
});

// 创建WebSocket服务器
const wss = new WebSocket.Server({ server });

// 存储所有连接的对等节点信息
const peers = new Map(); // key: websocket, value: {username, group, ip}

// 广播在线用户列表
function broadcastPeerList() {
    const peerList = Array.from(peers.values()).map(peer => ({
        username: peer.username,
        group: peer.group,
        ip: peer.ip
    }));

    const message = JSON.stringify({
        type: 'peerList',
        peers: peerList
    });

    peers.forEach((peerInfo, ws) => {
        if (ws.readyState === WebSocket.OPEN) {
            ws.send(message);
        }
    });
}

// 辅助函数：根据用户名和组名查找WebSocket
function findPeerWsByNameGroup(username, group) {
    for (const [ws, info] of peers.entries()) {
        if (info.username === username && info.group === group) {
            return ws;
        }
    }
    return null;
}

// WebSocket连接处理
wss.on('connection', (ws, req) => {
    const clientIP = req.socket.remoteAddress.replace(/^::ffff:/, '');
    console.log(`新对等节点连接：${clientIP}`);

    // 处理接收到的消息
    ws.on('message', (message) => {
        try {
            const data = JSON.parse(message);
            
            switch(data.type) {
                case 'register':
                    // 注册新对等节点
                    peers.set(ws, {
                        username: data.username,
                        group: data.group,
                        ip: clientIP
                    });
                    console.log(`节点注册: ${data.username} (${clientIP})`);
                    // 广播更新后的对等节点列表
                    broadcastPeerList();
                    break;

                case 'message':
                    // 用用户名+组名定位目标
                    const targetWs = findPeerWsByNameGroup(data.targetUsername, data.targetGroup);
                    if (targetWs && targetWs.readyState === WebSocket.OPEN) {
                        const senderInfo = peers.get(ws);
                        targetWs.send(JSON.stringify({
                            type: 'message',
                            fromUsername: senderInfo.username,
                            fromGroup: senderInfo.group,
                            fromIP: senderInfo.ip,
                            content: data.content
                        }));
                    }
                    break;

                case 'fileRequest':
                    // 转发文件传输请求
                    const targetForFile = Array.from(peers.entries())
                        .find(([_, info]) => info.ip === data.targetIP);
                    
                    if (targetForFile) {
                        const [targetWs] = targetForFile;
                        if (targetWs.readyState === WebSocket.OPEN) {
                            targetWs.send(JSON.stringify({
                                type: 'fileRequest',
                                from: clientIP,
                                fromUsername: peers.get(ws).username,
                                fileName: data.fileName,
                                fileSize: data.fileSize
                            }));
                        }
                    }
                    break;

                case 'fileChunk':
                    // 转发文件分片到目标对等节点
                    const targetWsFile = findPeerWsByNameGroup(data.targetUsername, data.targetGroup);
                    if (targetWsFile && targetWsFile.readyState === WebSocket.OPEN) {
                        targetWsFile.send(JSON.stringify({
                            type: 'fileChunk',
                            fromUsername: peers.get(ws).username,
                            fromGroup: peers.get(ws).group,
                            fileName: data.fileName,
                            fileSize: data.fileSize,
                            chunkIndex: data.chunkIndex,
                            totalChunks: data.totalChunks,
                            data: data.data
                        }));
                    }
                    break;
            }
        } catch (e) {
            console.error('消息处理错误:', e);
        }
    });

    // 处理客户端断开连接
    ws.on('close', () => {
        const peerInfo = peers.get(ws);
        if (peerInfo) {
            console.log(`节点断开: ${peerInfo.username} (${peerInfo.ip})`);
            peers.delete(ws);
            broadcastPeerList();
        }
    });
});
